package com.example.defaultshop;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Toast;

public class CheckoutActivity extends Activity {
	private ArrayList<String> earliest, latest;
	
	private ProgressBar progress;
	private RadioButton delivery;
	private RadioGroup group;
	private EditText name, cellphone, message, address, zipcode, city;
	private Spinner early, late;
	private Context context;
	private Button submit, back, home;

	private SharedPreferences preferences;
	private ShopApplication app;
	private OrderTask task;
	
	private boolean deliver;
	private int total, price;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_checkout);
		
		deliver = false;
		
		context = this;
		
		preferences = getSharedPreferences("DefaultShop", MODE_PRIVATE);

		app = (ShopApplication) getApplicationContext();
		
		total = getIntent().getExtras().getInt("total");
		if (total >= app.getShop().getDeliverFree() || !app.getShop().isDeliver()) {
			price = 0;
		} else if (total >= app.getShop().getDeliverMin()) {
			price = app.getShop().getDeliverPrice();
		} else {
			price = app.getShop().getDeliverPriceDefault();
		}

		progress = (ProgressBar) findViewById(R.id.progressBar1);
		message = (EditText) findViewById(R.id.txtMessage);
		
		name = (EditText) findViewById(R.id.txtName);
		name.setText(preferences.getString("name", ""));
		
		cellphone = (EditText) findViewById(R.id.txtCellphone);
		cellphone.setText(preferences.getString("phone", ""));
		
		address = (EditText) findViewById(R.id.txtAddress);
		zipcode = (EditText) findViewById(R.id.txtZipcode);
		city = (EditText) findViewById(R.id.txtCity);
		
		delivery = (RadioButton) findViewById(R.id.rbnDelivery);
		delivery.setText(getResources().getString(R.string.checkout_delivery) + " (" + (price > 0 ? "+" + price + ",-" : "Gratis") + ")");
		
		group = (RadioGroup) findViewById(R.id.rbgDelivery);
		group.setVisibility((app.getShop().isDeliver() ? View.VISIBLE : View.GONE));
		group.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				deliver = (checkedId == R.id.rbnDelivery);
				address.setVisibility((deliver ? View.VISIBLE : View.GONE));
				zipcode.setVisibility((deliver ? View.VISIBLE : View.GONE));
				city.setVisibility((deliver ? View.VISIBLE : View.GONE));
				setTimes();
				if (deliver && app.getShop().getDeliveryText().length() > 0) {
					AlertDialog.Builder builder = new AlertDialog.Builder(context);
		    		builder.setMessage(app.getShop().getDeliveryText())
		    		       .setTitle(R.string.obs)
		    		       .setPositiveButton(R.string.ok, null);
		    		AlertDialog dialog = builder.create();
		    		dialog.show();
				}
			}
		});
		
		back = (Button) findViewById(R.id.btnCheckoutBack);
		back.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
		home = (Button) findViewById(R.id.btnCheckoutHome);
		home.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), CampaignActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				startActivity(intent);
			}
		});
		
		submit = (Button) findViewById(R.id.btnSubmit);
		submit.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (app.getShop().getHours().equals("Lukket") || app.getShop().getOrders().equals("Lukket")) {
					Toast.makeText(v.getContext(), R.string.campaign_closed, Toast.LENGTH_LONG).show();
					Intent intent = new Intent(v.getContext(), CampaignActivity.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
					startActivity(intent);
					return;
				}
				try {
					if (early.getSelectedItemPosition() == 0 || late.getSelectedItemPosition() == 0) {
						Toast.makeText(v.getContext(), R.string.error_checkout_time, Toast.LENGTH_LONG).show();
						return;
					}

					String n = name.getText().toString();
					String p = cellphone.getText().toString();
					String a = address.getText().toString();
					String z = zipcode.getText().toString();
					String c = city.getText().toString();
					
					if (n.length() == 0) {
						Toast.makeText(v.getContext(), R.string.error_checkout_name, Toast.LENGTH_LONG).show();
						return;
					}
					if (p.length() == 0) {
						Toast.makeText(v.getContext(), R.string.error_checkout_cellphone, Toast.LENGTH_LONG).show();
						return;
					}
					if (p.length() != 8) {
						Toast.makeText(v.getContext(), R.string.error_checkout_cellphone_digits, Toast.LENGTH_LONG).show();
						return;
					}
					if (deliver) {
						if (a.length() == 0) {
							Toast.makeText(v.getContext(), R.string.error_checkout_address, Toast.LENGTH_LONG).show();
							return;
						}
						if (z.length() == 0) {
							Toast.makeText(v.getContext(), R.string.error_checkout_zipcode, Toast.LENGTH_LONG).show();
							return;
						}
						if (c.length() == 0) {
							Toast.makeText(v.getContext(), R.string.error_checkout_city, Toast.LENGTH_LONG).show();
							return;
						}
					}
					
					if (!isTimeAccepted()) {
						Toast.makeText(v.getContext(), getResources().getString(R.string.error_checkout_deadline_1) + " " + (deliver ? getResources().getString(R.string.error_checkout_deadline_delivery) : getResources().getString(R.string.error_checkout_deadline_pickup)) + " " + getResources().getString(R.string.error_checkout_deadline_2), Toast.LENGTH_LONG).show();
						setTimes();
						return;
					}

					progress.setVisibility(View.VISIBLE);
					submit.setVisibility(View.GONE);
					task = new OrderTask();
					task.execute();
				} catch (NumberFormatException e) {
					Toast.makeText(v.getContext(), R.string.error_time, Toast.LENGTH_LONG).show();
				}
			}
		});

		late = (Spinner) findViewById(R.id.late);
		late.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				v.performClick();
				View focus = getCurrentFocus();
				if (focus != null) {
					InputMethodManager manager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
					manager.hideSoftInputFromWindow(focus.getWindowToken(), 0);
				}
				return false;
			}
		});
		
		early = (Spinner) findViewById(R.id.early);
		early.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				v.performClick();
				View focus = getCurrentFocus();
				if (focus != null) {
					InputMethodManager manager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
					manager.hideSoftInputFromWindow(focus.getWindowToken(), 0);
				}
				return false;
			}
		});
		early.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
				latest = new ArrayList<String>();
				latest.add(getResources().getString(R.string.checkout_latest));
				for (int i = position; i < earliest.size(); i++)
					if (i > 0)
						latest.add(earliest.get(i));
				ArrayAdapter<String> adapter = new ArrayAdapter<String>(parent.getContext(), android.R.layout.simple_spinner_item, latest);
				adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
				late.setAdapter(adapter);
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				latest = new ArrayList<String>();
				latest.add(getResources().getString(R.string.checkout_latest));
				ArrayAdapter<String> adapter = new ArrayAdapter<String>(parent.getContext(), android.R.layout.simple_spinner_item, latest);
				adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
				late.setAdapter(adapter);
			}
		});
		
		setTimes();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		Calendar date = Calendar.getInstance();
		Calendar deadline = app.getShop().getDeadline();
		if (date.get(Calendar.YEAR) != deadline.get(Calendar.YEAR) || date.get(Calendar.MONTH) != deadline.get(Calendar.MONTH) || date.get(Calendar.DAY_OF_MONTH) != deadline.get(Calendar.DAY_OF_MONTH)) {
			Intent intent = new Intent(this, CampaignActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
		}
		
		if (app.getShop().getHours().equals("Lukket") || app.getShop().getOrders().equals("Lukket")) {
			Toast.makeText(this, R.string.campaign_closed, Toast.LENGTH_LONG).show();
			Intent intent = new Intent(this, CampaignActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return;
		}
		
		delivery.setVisibility(isDeliveryOpen() ? View.VISIBLE : View.INVISIBLE);
	}
	
	private boolean isDeliveryOpen() {
		if (app.getShop().getHours().equals("Lukket") || app.getShop().getOrders().equals("Lukket"))
			return false;
			
		try {
			String[] early = app.getShop().getDelivery().split("-")[0].split(":");
			String[] late = app.getShop().getDelivery().split("-")[1].split(":");
			int eh = Integer.parseInt(early[0]);
			int em = Integer.parseInt(early[1]);
			int lh = Integer.parseInt(late[0]);
			int lm = Integer.parseInt(late[1]);
			
			Calendar calendar = Calendar.getInstance();
			float now = calendar.getTimeInMillis();
			
			calendar.set(Calendar.HOUR_OF_DAY, eh);
			calendar.set(Calendar.MINUTE, em);
			if (calendar.getTimeInMillis() - now > 0)
				return false;
			
			calendar.set(Calendar.HOUR_OF_DAY, lh);
			calendar.set(Calendar.MINUTE, lm);
			if (calendar.getTimeInMillis() - now <= 0)
				return false;
		} catch (NumberFormatException e) {
			return false;
		} catch (IndexOutOfBoundsException e) {
			return false;
		}
		return true;
	}
	
	private boolean isTimeAccepted() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, (deliver ? app.getShop().getTimeDeliver() : app.getShop().getTimeNormal()));
		String t = (String)(early.getSelectedItem());
		float now = calendar.getTimeInMillis();
		calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(t.split(":")[0]));
		calendar.set(Calendar.MINUTE, Integer.parseInt(t.split(":")[1]));
		return !(calendar.getTimeInMillis() - now < 0);
	}
	
	private void setTimes() {
		Calendar start = Calendar.getInstance();
		start.add(Calendar.MINUTE, (deliver ? app.getShop().getTimeDeliver() : app.getShop().getTimeNormal()) + 5);
		int hour = Integer.parseInt(app.getShop().getHours().split("-")[0].split(":")[0]);
		int minute = Integer.parseInt(app.getShop().getHours().split("-")[0].split(":")[1]);
		if (start.get(Calendar.HOUR_OF_DAY) >= hour) {
			hour = start.get(Calendar.HOUR_OF_DAY);
			minute = 5 * (Math.round(start.get(Calendar.MINUTE) / 5));
		}
		start.set(Calendar.HOUR_OF_DAY, hour);
		start.set(Calendar.MINUTE, minute);
		
		Calendar end = (Calendar) start.clone();
		end.set(Calendar.HOUR_OF_DAY, Integer.parseInt(app.getShop().getHours().split("-")[1].split(":")[0]));
		end.set(Calendar.MINUTE, Integer.parseInt(app.getShop().getHours().split("-")[1].split(":")[1]));
		
		earliest = new ArrayList<String>();
		earliest.add(getResources().getString(R.string.checkout_early));
		
		if (start.getTimeInMillis() >= end.getTimeInMillis())
			end.add(Calendar.DAY_OF_MONTH, 1);
		
		while (start.getTimeInMillis() <= end.getTimeInMillis()) {
			hour = start.get(Calendar.HOUR_OF_DAY);
			minute = start.get(Calendar.MINUTE);
			earliest.add(hour + ":" + (minute < 10 ? "0" : "") + minute);
			start.add(Calendar.MINUTE, 5);
		}
		
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, earliest);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		early.setAdapter(adapter);
	}
	
	private class OrderTask extends AsyncTask<Void, Void, Boolean> {
		private int orderId;
		
    	@Override
		protected Boolean doInBackground(Void... params) {
    		String n = name.getText().toString();
    		String p = cellphone.getText().toString();
    		String a = address.getText().toString();
    		String z = zipcode.getText().toString();
    		String c = city.getText().toString();
    		String m = (message.getText().length() > 0 ? message.getText().toString() : "Ingen besked");
    		String d = (String) early.getSelectedItem();
    		String l = (String) late.getSelectedItem();
    		try {
				InputStream in = Server.post(Server.ORDER, Server.getOrderXml(n, p, m, d, l, a, z, c, app.getShop().getIdx(), app.getBasketId(), 0, (deliver ? 1 : 0)));
				XmlPullParser parser = Server.toXmlParser(in);
				orderId = XmlParser.getOrderId(parser);
			} catch (IOException e) {
				Log.e("Shop", "IOException: " + e.getMessage());
				return false;
			} catch (XmlPullParserException e) {
				Log.e("Shop", "XmlPullParserException: " + e.getMessage());
				return false;
			} catch (NullPointerException e) {
				Log.e("Shop", "NullPointerException: " + e.getMessage());
				return false;
			} catch (IllegalArgumentException e) {
				Log.e("Shop", "IllegalArgumentException: " + e.getMessage());
				return false;
			}
    		return true;
    	}
    	
    	@Override
	    protected void onPostExecute(Boolean success) {
	    	if (success) {
	    		Intent intent = new Intent(context, StatusActivity.class);
	    		intent.putExtra("orderId", orderId);
	    		startActivity(intent);
	    	} else {
	    		AlertDialog.Builder builder = new AlertDialog.Builder(context);
	    		builder.setMessage(R.string.error_send_order)
	    		       .setTitle(R.string.error)
	    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								task = new OrderTask();
								task.execute();
								progress.setVisibility(View.VISIBLE);
								submit.setVisibility(View.GONE);
							}
						})
						.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								finish();
							}
						});
	    		AlertDialog dialog = builder.create();
	    		dialog.show();
	    	}
			progress.setVisibility(View.GONE);
			submit.setVisibility(View.VISIBLE);
    	}
	}
}